#include "Ai.h"


void Ai::go() {
    ChessPos pos = think();
    Sleep(1000);
    chess->chessDown(&pos, CHESS_WHITE);
}

void Ai::init(Chess *chess) {
    this->chess = chess;
    for (int i = 0; i < chess->getGradeSize(); i++) {
        vector<int> row;
        for (int j = 0; j < chess->getGradeSize(); ++j) {
            row.push_back(0);
        }
        this->scoreMap.push_back(row);
    }
}

// todo 优化！
void Ai::calculateScore() {
    int personNum = 0;// 棋手该方向连起来的棋子数量
    int aiNum = 0;// 电脑该方向连起来的棋子数量
    int emptyNum = 0;// 该方向上空位的数量
    // 评分向量数组清零
    for (auto &i: scoreMap) {
        for (int &j: i) {
            j = 0;
        }
    }
    int size = chess->getGradeSize();
    // 遍历棋盘
    for (int row = 0; row < size; row++) {
        for (int col = 0; col < size; col++) {

            if (chess->getChessData(row, col)) {
                continue;
            }
            // -1朝左，1朝右，0原地
            for (int y = -1; y <= 0; ++y) { // y 只能等于-1  0
                for (int x = -1; x <= 1; ++x) { // x 只能等于-1  0  1
                    if (y == 0 && x == 0) continue;
                    if (y == 0 && x != 1) continue;//当y = 0,x = 1

                    //清零计算
                    personNum = 0;
                    aiNum = 0;
                    emptyNum = 0;
                    // 假设黑棋在该位置落子,会构成什么棋形
                    for (int i = 1; i <= 4; ++i) {
                        int curRow = row + i * y;
                        int curCol = col + i * x;
                        // 判断落子是否合法
                        if (curRow >= 0 && curRow < size
                            && curCol >= 0 && curCol < size
                            && chess->getChessData(curRow, curCol) == CHESS_BLACK) {
                            personNum++;
                        } else if (curRow >= 0 && curRow < size
                                   && curCol >= 0 && curCol < size
                                   && chess->getChessData(curRow, curCol) == CHESS_NONE) {
                            emptyNum++;
                            break;
                        } else {
                            break;
                        }
                    }

                    // 反向继续计算
                    for (int i = 1; i <= 4; i++) {
                        int curRow = row - i * y;
                        int curCol = col - i * x;

                        if (curRow >= 0 && curRow < size &&
                            curCol >= 0 && curCol < size &&
                            chess->getChessData(curRow, curCol) == 1) {
                            personNum++;
                        } else if (curRow >= 0 && curRow < size &&
                                   curCol >= 0 && curCol < size &&
                                   chess->getChessData(curRow, curCol) == 0) {
                            emptyNum++;
                            break;
                        } else {
                            break;
                        }
                    }


                    if (personNum == 1) {//连2
                        scoreMap[row][col] += 10;
                    } else if (personNum == 2) {
                        if (emptyNum == 1) {// 死3，即有一边被堵住了
                            scoreMap[row][col] += 30;
                        } else if (emptyNum == 2) {//活3
                            scoreMap[row][col] += 40;
                        }
                    } else if (personNum == 3) {
                        if (emptyNum == 1) {// 死4，一边被堵住了
                            scoreMap[row][col] += 60;
                        } else if (emptyNum == 2) {
                            scoreMap[row][col] += 200;
                        }
                    } else if (personNum == 4) {// 黑棋赢了
                        scoreMap[row][col] += 20000;
                    }

                    // 假设白棋在该位置落子
                    emptyNum = 0;
                    for (int i = 1; i <= 4; ++i) {
                        int curRow = row + i * y;
                        int curCol = col + i * x;
                        if (curRow >= 0 && curRow < size
                            && curCol >= 0 && curCol < size
                            && chess->getChessData(curRow, curCol) == CHESS_WHITE) {
                            aiNum++;
                        } else if (curRow >= 0 && curRow < size
                                   && curCol >= 0 && curCol < size
                                   && chess->getChessData(curRow, curCol) == CHESS_NONE) {
                            emptyNum++;
                        } else {
                            break;
                        }
                    }

                    for (int i = 1; i <= 4; i++) {
                        int curRow = row - i * y;
                        int curCol = col - i * x;

                        if (curRow >= 0 && curRow < size &&
                            curCol >= 0 && curCol < size &&
                            chess->getChessData(curRow, curCol) == -1) {
                            aiNum++;
                        }
                        else if (curRow >= 0 && curRow < size &&
                                 curCol >= 0 && curCol < size &&
                                 chess->getChessData(curRow, curCol) == 0) {
                            emptyNum++;
                            break;
                        }
                        else {
                            break;
                        }
                    }


                    if (aiNum == 0) {
                        scoreMap[row][col] += 5;
                    } else if (aiNum == 1) {
                        scoreMap[row][col] += 10;
                    } else if (aiNum == 2) {
                        if (emptyNum == 1) {
                            scoreMap[row][col] += 25;
                        } else if (emptyNum == 2) {
                            scoreMap[row][col] += 50;
                        }
                    } else if (aiNum == 3) {
                        if (emptyNum == 1) {// 死4，一边被堵住了
                            scoreMap[row][col] += 60;
                        } else if (emptyNum == 2) {
                            scoreMap[row][col] += 10000;
                        }
                    } else if (aiNum == 4) {
                        scoreMap[row][col] = 30000;
                    }
                }
            }
        }
    }
}

ChessPos Ai::think() {
    calculateScore();
    vector<ChessPos> maxPoints;
    int maxScore = 0;
    int size = chess->getGradeSize();
    for (int row = 0; row < size; ++row) {
        for (int col = 0; col < size; ++col) {
            if (chess->getChessData(row, col) == CHESS_NONE) {
                if (scoreMap[row][col] > maxScore) {
                    maxScore = scoreMap[row][col];
                    maxPoints.clear();
                    maxPoints.push_back(ChessPos(row,col));
                } else if (scoreMap[row][col] == maxScore) {
                    maxPoints.push_back(ChessPos(row,col));
                }
            }
        }
    }
    int index = rand() % maxPoints.size();
    return maxPoints[index];
}
